#include "pack_make_parsing.h"

#include <esp_chip_info.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#include "cJSON.h"
#include "data_define.h"
#include "esp_log.h"
#include "esp_mac.h"
#include "time.h"

void make_register_pack(char *buf, g_cfg_t *cfg) {
  uint8_t id[6];
  char chbuf[30];
  uint32_t time_stamp = 1753670965; /* 获取当前时间戳 */
  cJSON *root = cJSON_CreateObject();
  cJSON_AddStringToObject(root, "type", "register");
  cJSON *payload = cJSON_AddObjectToObject(root, "payload");
  esp_base_mac_addr_get(id);
  sprintf(chbuf, MACSTR, MAC2STR(id));
  cJSON_AddStringToObject(payload, "device_mac", chbuf);
  cJSON_AddNumberToObject(payload, "time", time_stamp);
  cJSON_AddStringToObject(payload, "timezone", "UTC+8");
  cJSON *json_cfg = cJSON_AddObjectToObject(payload, "cfg");
  cJSON_AddStringToObject(json_cfg, "wifi_ssid", cfg->wifi_ssid);
  cJSON_AddStringToObject(json_cfg, "wifi_pass", cfg->wifi_pass);
  cJSON_AddStringToObject(json_cfg, "tcp_server_ip", cfg->tcp_server_ip);
  cJSON_AddNumberToObject(json_cfg, "tcp_server_port", cfg->tcp_server_port);
  sprintf(chbuf, "%.2f", cfg->temp_k);
  cJSON_AddRawToObject(json_cfg, "temp_k", chbuf);
  sprintf(chbuf, "%.2f", cfg->temp_b);
  cJSON_AddRawToObject(json_cfg, "temp_b", chbuf);
  sprintf(chbuf, "%.2f", cfg->humi_k);
  cJSON_AddRawToObject(json_cfg, "humi_k", chbuf);
  sprintf(chbuf, "%.2f", cfg->humi_b);
  cJSON_AddRawToObject(json_cfg, "humi_b", chbuf);
  cJSON_AddNumberToObject(json_cfg, "collect_interval", cfg->collect_interval);
  cJSON_AddNumberToObject(json_cfg, "upload_interval", cfg->upload_interval);
  char *buf_str = cJSON_PrintUnformatted(root);
  strcpy(buf, buf_str);
  cJSON_free(buf_str);
  cJSON_Delete(root);
  return;
}
parse_result_e parse_regiser_ack_pack(char *buf) {

  parse_result_e ret = PARSE_OK;
  cJSON *root = NULL;
  cJSON *type = NULL;
  cJSON *payload = NULL;
  cJSON *device_mac = NULL;
  cJSON *timestamp = NULL;
  cJSON *timezone = NULL;
  root = cJSON_Parse(buf);
  if (!root) {
    ret = PARSE_INVALID_JSON;
    goto fail;
  }
  type = cJSON_GetObjectItemCaseSensitive(root, "type");
  if (!cJSON_IsString(type) || !type->valuestring) {
    ret = PARSE_MISSING_FIELD;
    goto fail;
  }
  if (strcmp(type->valuestring, "register_ack") != 0) {
    ret = PARSE_TYPE_MISMATCH;
    goto fail;
  }
  payload = cJSON_GetObjectItemCaseSensitive(root, "payload");
  if (!cJSON_IsObject(payload)) {
    ret = PARSE_MISSING_FIELD;
    goto fail;
  }
  device_mac = cJSON_GetObjectItemCaseSensitive(payload, "device_mac");
  if (!cJSON_IsString(device_mac) || !device_mac->valuestring) {
    ret = PARSE_MISSING_FIELD;
    goto fail;
  } else if (1 /* 判定是否是给自己的 */) {
  } else {
    /* mac 不是给自己的 */
    ret = PARSE_NO_MY_DEVICE;
    goto fail;
  }
  timestamp = cJSON_GetObjectItemCaseSensitive(payload, "time");
  if (!cJSON_IsNumber(timestamp)) {
    ret = PARSE_MISSING_FIELD;
    goto fail;
  } else {
    /* TODO: 进行时间同步*/
  }
  timezone = cJSON_GetObjectItemCaseSensitive(payload, "timezone");
  if (!cJSON_IsString(timezone) || !timezone->valuestring) {
    ret = PARSE_MISSING_FIELD;
    goto fail;
  } else {
    /* TODO: 设置系统时区*/
  }
  ret = PARSE_OK;
  goto done;

fail:
  if (root) {
    cJSON_Delete(root);
  }
  return ret;
done:
  if (root) {
    cJSON_Delete(root);
  }
  return ret;
}

parse_result_e parse_sync_pack(char *buf, g_cfg_t *out_cfg) {
  g_cfg_t tp_cfg;
  parse_result_e ret = PARSE_OK;
  cJSON *root = NULL;
  cJSON *type = NULL;
  cJSON *payload = NULL;
  cJSON *device_mac = NULL;
  cJSON *timestamp = NULL;
  cJSON *timezone = NULL;
  cJSON *cfg = NULL;
  cJSON *wifi_ssid = NULL, *wifi_pass = NULL;
  cJSON *server_tcp_ip = NULL;
  cJSON *server_tcp_port = NULL;
  cJSON *temp_k = NULL, *temp_b = NULL;
  cJSON *humi_k = NULL, *humi_b = NULL;
  cJSON *collect_interval = NULL, *upload_interval = NULL;

  root = cJSON_Parse(buf);
  if (!root) {
    ret = PARSE_INVALID_JSON;
    goto fail;
  }
  type = cJSON_GetObjectItemCaseSensitive(root, "type");
  if (!cJSON_IsString(type) || !type->valuestring) {
    ret = PARSE_MISSING_FIELD;
    goto fail;
  }
  payload = cJSON_GetObjectItemCaseSensitive(root, "payload");
  if (!cJSON_IsObject(payload)) {
    ret = PARSE_MISSING_FIELD;
    goto fail;
  }
  device_mac = cJSON_GetObjectItemCaseSensitive(payload, "device_mac");
  if (!cJSON_IsString(device_mac) || !device_mac->valuestring) {
    ret = PARSE_MISSING_FIELD;
    goto fail;
  } else if (1 /* 判定是否是给自己的 */) {
  } else {
    /* mac 不是给自己的 */
    ret = PARSE_NO_MY_DEVICE;
    goto fail;
  }
  cfg = cJSON_GetObjectItemCaseSensitive(payload, "cfg");
  if (!cJSON_IsObject(cfg)) {
    ret = PARSE_MISSING_FIELD;
    goto fail;
  }
  wifi_ssid = cJSON_GetObjectItemCaseSensitive(cfg, "wifi_ssid");
  wifi_pass = cJSON_GetObjectItemCaseSensitive(cfg, "wifi_pass");
  server_tcp_ip = cJSON_GetObjectItemCaseSensitive(cfg, "server_tcp_ip");
  server_tcp_port = cJSON_GetObjectItemCaseSensitive(cfg, "server_tcp_port");
  temp_k = cJSON_GetObjectItemCaseSensitive(cfg, "temp_k");
  temp_b = cJSON_GetObjectItemCaseSensitive(cfg, "temp_b");
  humi_k = cJSON_GetObjectItemCaseSensitive(cfg, "humi_k");
  humi_b = cJSON_GetObjectItemCaseSensitive(cfg, "humi_b");
  collect_interval = cJSON_GetObjectItemCaseSensitive(cfg, "collect_interval");
  upload_interval = cJSON_GetObjectItemCaseSensitive(cfg, "upload_interval");
  if (!cJSON_IsString(wifi_ssid)             /*  */
      || !cJSON_IsString(wifi_pass)          /*  */
      || !cJSON_IsString(server_tcp_ip)      /*  */
      || !cJSON_IsNumber(server_tcp_port)    /*  */
      || !cJSON_IsNumber(temp_k)             /*  */
      || !cJSON_IsNumber(temp_b)             /*  */
      || !cJSON_IsNumber(humi_k)             /*  */
      || !cJSON_IsNumber(humi_b)             /*  */
      || !cJSON_IsNumber(collect_interval)   /*  */
      || !cJSON_IsNumber(upload_interval)) { /*  */
    ret = PARSE_MISSING_FIELD;
    goto fail;
  } else {
    memcpy(tp_cfg.wifi_ssid, wifi_ssid->valuestring,
           strlen(wifi_ssid->valuestring));
    memcpy(tp_cfg.wifi_pass, wifi_pass->valuestring,
           strlen(wifi_pass->valuestring));
    memcpy(tp_cfg.tcp_server_ip, server_tcp_ip->valuestring,
           strlen(server_tcp_ip->valuestring));
    tp_cfg.tcp_server_port = server_tcp_port->valueint;
    tp_cfg.temp_k = temp_k->valuedouble;
    tp_cfg.temp_b = temp_b->valuedouble;
    tp_cfg.humi_k = humi_k->valuedouble;
    tp_cfg.humi_b = humi_b->valuedouble;
    tp_cfg.collect_interval = (int)collect_interval->valuedouble;
    tp_cfg.upload_interval = (int)upload_interval->valuedouble;
  }
  ret = PARSE_OK;
  memcpy(out_cfg, &tp_cfg, sizeof(g_cfg_t));
  goto done;
fail:

  if (root) {
    cJSON_Delete(root);
  }
  return ret;
done:
  if (root) {
    cJSON_Delete(root);
  }
  return ret;
}
void make_sycn_ack_pack(char *buf) {
  cJSON *root = cJSON_CreateObject();
  cJSON_AddStringToObject(root, "type", "ack_sync_cfg");

  char *buf_str = cJSON_PrintUnformatted(root);
  strcpy(buf, buf_str);
  cJSON_free(buf_str);
  cJSON_Delete(root);
  return;
}
void make_realtime_pack(char *buf, float H, float T, uint32_t timestamp) {
  char fbuffer[32];
  cJSON *root = cJSON_CreateObject();
  cJSON_AddStringToObject(root, "type", "real_time_data");
  cJSON *payload = cJSON_AddObjectToObject(root, "payload");
  cJSON_AddStringToObject(payload, "device_mac", g_mac_str);
  cJSON_AddNumberToObject(payload, "timestamp", timestamp);
  sprintf(fbuffer, "%.2f", H);
  cJSON_AddRawToObject(payload, "h", fbuffer);
  sprintf(fbuffer, "%.2f", T);
  cJSON_AddRawToObject(payload, "t", fbuffer);

  char *buf_str = cJSON_PrintUnformatted(root);
  strcpy(buf, buf_str);
  cJSON_free(buf_str);
  cJSON_Delete(root);
}
uint8_t parse_real_time_ack_pack(char *buf) {
  cJSON *root = cJSON_Parse(buf);
  if (!root)
    return false;

  cJSON *type = cJSON_GetObjectItemCaseSensitive(root, "type");
  bool result =
      cJSON_IsString(type) && strcmp(type->valuestring, "ack_data") == 0;

  cJSON_Delete(root);
  return result;
}

parse_result_e parse_json_pack(char *buf, g_cfg_t *out_cfg) { return PARSE_OK; }
